package com.itheima.ums.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.mall.exception.BusinessException;
import com.itheima.mall.exception.ErrorResult;
import com.itheima.mall.pojo.*;
import com.itheima.mall.vo.PageResult;
import com.itheima.ums.mapper.*;
import com.itheima.ums.service.UmsRoleService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class UmsRoleServiceImpl implements UmsRoleService {

    @Autowired
    private UmsRoleMapper umsRoleMapper;

    @Autowired
    private RoleWithMenuMapper roleWithMenuMapper;

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private RoleWithResourceMapper roleWithResourceMapper;

    @Autowired
    private ResourceMapper resourceMapper;

    @Autowired
    private AdminWithRoleMapper adminWithRoleMapper;

    //根据角色名称分页获取角色列表
    public PageResult list(Integer pageNum, Integer pageSize, String keyword) {

        Page page = new Page(pageNum, pageSize);
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        //关键字存在就匹配关键字查询
        queryWrapper.like(StringUtils.isNotEmpty(keyword), Role::getName, keyword);

        umsRoleMapper.selectPage(page, queryWrapper);

        return new PageResult(pageNum, pageSize, (int) page.getTotal(), page.getRecords());
    }

    //查询所有角色信息
    public List<Role> listAll() {
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Role::getSort);

        return umsRoleMapper.selectList(queryWrapper);
    }

    //查询菜单信息
    public List<Menu> getMenuListById(Long roleId) {
        LambdaQueryWrapper<RoleMenuRelation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RoleMenuRelation::getRoleId, roleId);
        List<RoleMenuRelation> list = roleWithMenuMapper.selectList(queryWrapper);

        List<Long> menuIds = CollUtil.getFieldValues(list, "menuId", Long.class);
        if (CollUtil.isEmpty(menuIds)) {
            return new ArrayList<>();
        }
        List<Menu> menus = menuMapper.selectBatchIds(menuIds);
        return menus;
    }

    //获取角色相关资源
    public List<Resource> listResource(Long roleId) {

        LambdaQueryWrapper<RoleResourceRelation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RoleResourceRelation::getRoleId, roleId);
        List<RoleResourceRelation> list = roleWithResourceMapper.selectList(queryWrapper);
        List<Long> resourceIds = CollUtil.getFieldValues(list, "resourceId", Long.class);

        if (CollUtil.isEmpty(resourceIds)) {
            return new ArrayList<>();
        }
        return resourceMapper.selectBatchIds(resourceIds);

    }

    //给角色分配菜单
    public Integer allocMenu(Long roleId, List<Integer> menuIds) {
        LambdaQueryWrapper<RoleMenuRelation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RoleMenuRelation::getRoleId, roleId);
        if (!CollUtil.isEmpty(menuIds)){
            roleWithMenuMapper.delete(queryWrapper);
        }
        int count = 0;
        for (Integer menuId : menuIds) {
            RoleMenuRelation relation = new RoleMenuRelation();
            relation.setRoleId(roleId);
            relation.setMenuId(Long.valueOf(menuId));
            count = roleWithMenuMapper.insert(relation);
            count++;
        }

        return count;
    }

    //给角色分配资源
    public Integer allocResource(Long roleId, List<Integer> resourceIds) {
        LambdaQueryWrapper<RoleResourceRelation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RoleResourceRelation::getRoleId, roleId);
        roleWithResourceMapper.delete(queryWrapper);
        int count = 0;
        for (Integer resource : resourceIds) {
            RoleResourceRelation relation = new RoleResourceRelation();
            relation.setRoleId(roleId);
            relation.setResourceId(Long.valueOf(resource));
            count = roleWithResourceMapper.insert(relation);
            count++;
        }

        return count;
    }

    //添加角色
    public Integer createRole(Role role) {
        role.setCreateTime(new Date());
        role.setAdminCount(0l);
        role.setSort(0l);
        return umsRoleMapper.insert(role);
    }

    //批量删除角色
    public Integer deleteByIds(List<Long> ids) {
        LambdaQueryWrapper<RoleMenuRelation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(RoleMenuRelation::getRoleId, ids);
        LambdaQueryWrapper<RoleResourceRelation> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.in(RoleResourceRelation::getRoleId, ids);
        LambdaQueryWrapper<AdminRoleRelation> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.in(AdminRoleRelation::getRoleId, ids);
        boolean exists = roleWithMenuMapper.exists(queryWrapper);
        boolean exists1 = roleWithResourceMapper.exists(queryWrapper1);
        boolean exists2 = adminWithRoleMapper.exists(queryWrapper2);
        if (exists) {
            roleWithMenuMapper.delete(queryWrapper);
        }
        if (exists1) {
            roleWithResourceMapper.delete(queryWrapper1);
        }
        if (exists2) {
            throw new BusinessException(ErrorResult.loginAccountError());
        }

        return umsRoleMapper.deleteBatchIds(ids);
    }

    //修改角色
    public Integer updateById(Role role, Long id) {
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Role::getId, id);
        return umsRoleMapper.update(role, queryWrapper);
    }

    //修改角色状态
    public Integer updateStatus(Long id, Long status) {
        LambdaUpdateWrapper<Role> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(Role::getStatus, status).eq(Role::getId, id);
        return umsRoleMapper.update(null, updateWrapper);
    }
}
